<!-- DynamicForm.vue -->
<template>
  <div class="dynamic-form">
    <el-form ref="dynamicForm" :model="formData" :rules="formRules" label-width="120px">
      <template v-for="(group, groupName) in config">
        <div class="form-group" :key="groupName">
          <div class="group-title">{{ groupName }}</div>
          <el-row :gutter="20">
            <template v-for="(param, paramName) in group">
              <el-col :span="24" :key="paramName">
                <el-form-item :label="param.label" :prop="paramName">
                  <!-- 字符串类型 -->
                  <el-input v-if="param.type === 'str'" v-model="formData[paramName]" :placeholder="param.placeholder"
                    :disabled="!param.editable" />

                  <!-- 文本类型 -->
                  <el-input v-else-if="param.type === 'text'" v-model="formData[paramName]" type="textarea"
                    :placeholder="param.placeholder" :disabled="!param.editable" />

                  <!-- 整数类型 -->
                  <el-input-number v-else-if="param.type === 'int'" v-model="formData[paramName]"
                    :min="getMinValue(param.range)" :max="getMaxValue(param.range)" :disabled="!param.editable"
                    controls-position="right" />

                  <!-- 浮点数类型 -->
                  <el-input-number v-else-if="param.type === 'float'" v-model="formData[paramName]"
                    :min="getMinValue(param.range)" :max="getMaxValue(param.range)" :disabled="!param.editable"
                    controls-position="right" :step="0.1" />

                  <!-- 布尔类型 -->
                  <el-switch v-else-if="param.type === 'bool'" v-model="formData[paramName]"
                    :disabled="!param.editable" />

                  <!-- 下拉选择类型 -->
                  <el-select v-else-if="param.type === 'list' || (param.choice && param.choice.length > 0)"
                    v-model="formData[paramName]" :placeholder="param.placeholder" :disabled="!param.editable"
                    clearable>
                    <el-option v-for="(option, index) in (param.choice || [])" :key="index" :label="option"
                      :value="option" />
                  </el-select>

                  <!-- JSON类型 -->
                  <el-input v-else-if="param.type === 'json'" v-model="formData[paramName]" type="textarea"
                    :placeholder="param.placeholder" :disabled="!param.editable" />
                </el-form-item>
              </el-col>
            </template>
          </el-row>
        </div>
      </template>
    </el-form>

    <div class="form-actions">
      <el-button type="primary" @click="submitForm">确定</el-button>
      <el-button @click="resetForm">重置</el-button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DynamicForm',
  props: {
    config: {
      type: Object,
      required: true
    },
    modelValue: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      formData: {},
      formRules: {}
    };
  },
  watch: {
    config: {
      handler() {
        this.initForm();
      },
      immediate: true
    },
    modelValue: {
      handler(val) {
        this.formData = { ...val };
      },
      immediate: true,
      deep: true
    }
  },
  mounted() {
    this.initForm();
  },
  methods: {
    initForm() {
      // 初始化表单数据和验证规则
      const data = {};
      const rules = {};

      for (const groupName in this.config) {
        const group = this.config[groupName];
        for (const paramName in group) {

          const param = group[paramName];
          // 设置默认值
          data[paramName] = this.modelValue[paramName] !== undefined
            ? this.modelValue[paramName]
            : param.default;

          // 设置验证规则
          if (param.require) {
            rules[paramName] = [
              { required: true, message: `${param.label}不能为空`, trigger: 'blur' }
            ];
          }
        }
      }

      this.formData = data;
      this.formRules = rules;
    },

    getMinValue(range) {
      if (!range) return -Infinity;
      const [min] = range.split(',').map(Number);
      return isNaN(min) ? -Infinity : min;
    },

    getMaxValue(range) {
      if (!range) return Infinity;
      const [, max] = range.split(',').map(Number);
      return isNaN(max) ? Infinity : max;
    },

    submitForm() {
      this.$refs.dynamicForm.validate((valid) => {
        if (valid) {
          this.$emit('update:modelValue', this.formData);
          this.$emit('submit', this.formData);
        } else {
          this.$message.warning('请检查表单填写是否正确');
          return false;
        }
      });
    },

    resetForm() {
      this.$refs.dynamicForm.resetFields();
    }
  }
};
</script>

<style scoped>
.dynamic-form {
  padding: 10px;
  height: calc(100% - 46px);
  position: relative;
}

.form-group {
  margin-bottom: 30px;
}

.group-title {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.form-actions {
  text-align: center;
  padding-top: 10px;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 50px;
  border-top: 1px solid var(--ui-border-color-base);
}
</style>